   // ******************************************************
   //
   // Copyright 2011 OpenAjax Alliance
   //
   // Licensed under the Apache License, Version 2.0 (the "License");
   // you may not use this file except in compliance with the License.
   // You may obtain a copy of the License at
   //
   //    http://www.apache.org/licenses/LICENSE-2.0
   //
   // Unless required by applicable law or agreed to in writing, software
   // distributed under the License is distributed on an "AS IS" BASIS,
   // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   // See the License for the specific language governing permissions and
   // limitations under the License.
   //
   // ******************************************************

Components.utils.import("resource://oaacacheinspector/cache-inspector-common.js");

if (typeof(OAA_CI) == "undefined") {
  var OAA_CI = {};
}

/** ================================================================
*
* OAACacheInspector Initialize properites
*
*
* =============================================================== */

OAA_CI.evaluation = null;
OAA_CI.last_node = null;


/** ================================================================
*
* onLoad
*
* @desc onLoad event handler that initializes object properties
*
* @return nothing
*
* =============================================================== */

OAA_CI.onLoad = function(cache) {
  OAA_CI.initialized = true;
  OAA_CI.oaa_log_window = null;
  OAA_CI.oaa_results_window = null;

  if (OAA_CI.links)         OAA_CI.links.onLoad();
  if (OAA_CI.lists)         OAA_CI.lists.onLoad();
  if (OAA_CI.headland)      OAA_CI.headland.onLoad();
  if (OAA_CI.controls)      OAA_CI.controls.onLoad();
  if (OAA_CI.tables)        OAA_CI.tables.onLoad();
  if (OAA_CI.images)        OAA_CI.images.onLoad();
  if (OAA_CI.media)         OAA_CI.media.onLoad();
  if (OAA_CI.abbreviations) OAA_CI.abbreviations.onLoad();
  if (OAA_CI.color)         OAA_CI.color.onLoad();
  if (OAA_CI.elements)      OAA_CI.elements.onLoad();

}

/** ================================================================
*
* onLoad
*
* @desc onLoad event handler that initializes object properties
*
* @return nothing
*
* =============================================================== */

OAA_CI.updateXULTime = function (start_time) {

  var end_time = new Date().getTime();
  var time = end_time - start_time;

  if (OAA_CI.prog_xul_message) {
  OAA_CI.prog_xul_message.value = "XUL update time: " + time + " milliseconds";
  }

}



/** ================================================================
*
* updateEvaluationResults
*
* @desc updates evaluation results window with the results of the last evaluation
*
* @return nothing
*
* =============================================================== */

OAA_CI.updateEvaluationResults = function() {

  if (OAA_CI.oaa_result_window &&
      OAA_CI.oaa_result_window.document) {

    var oaa_result_text = OAA_CI.oaa_result_window.document.getElementById('ID_OAA_RESULT_TEXT');

    if (oaa_result_text &&
        OAA_CI.evaluation.ruleset_result) {
      oaa_result_text.value =  OAA_CI.evaluation.ruleset_result.toString();
    }

    var oaa_result_html = OAA_CI.oaa_result_window.document.getElementById('ID_OAA_RESULT_HTML');
    if (oaa_result_html &&
        OAA_CI.evaluation.ruleset_result) {
      oaa_result_html.value =  OAA_CI.evaluation.ruleset_result.toHTML();
    }

    var oaa_result_xml = OAA_CI.oaa_result_window.document.getElementById('ID_OAA_RESULT_XML');
    if (oaa_result_xml &&
        OAA_CI.evaluation.ruleset_result) {
      oaa_result_xml.value =  OAA_CI.evaluation.ruleset_result.toXML(OAA_CI.evaluation.ruleset_nls);
    }

    var oaa_result_json = OAA_CI.oaa_result_window.document.getElementById('ID_OAA_RESULT_JSON');
    if (oaa_result_json && OAA_CI.evaluation.ruleset_result) {
      oaa_result_json.value =  OAA_CI.evaluation.ruleset_result.toJSON();
    }

    OAA_CI.oaa_result_window.sizeToContent();
  }
}

/** ================================================================
*
* onEvaluationResultsCommand
*
* @desc opens the log information window
*
* @return nothing
*
* =============================================================== */

OAA_CI.onEvaluationResultsCommand = function() {

  if (OAA_CI.oaa_result_window &&
      !OAA_CI.oaa_result_window.closed) {
    OAA_CI.updateEvaluationResults();
  }
  else {
    OAA_CI.oaa_result_window = window.open("chrome://oaaruletesting/content/oaa-result-window.xul",
                      "oaaResultWindow", "chrome,centerscreen");
    OAA_CI.oaa_log_window.onload = OAACacheInspector.updateEvaluationResults;
  }

}

/** ================================================================
*
* updateProgress
*
* @desc updated progress information on evaluating a document
*
* @return nothing
*
* =============================================================== */

OAA_CI.updateProgress = function (message, percent) {

  if (OAA_CI.prog_meter) {
    OAA_CI.prog_meter.value = percent;
  }

  if (OAA_CI.prog_message) {
    OAA_CI.prog_message.value = message;
  }

}

/** ================================================================
*
* highlightCacheItem
*
* @desc cache_item Object OAA Cache item
*
* @return nothing
*
* =============================================================== */

OAA_CI.highlightCacheItem = function(cache_item) {

  var node = null;
  var pos_top;
  var pos_left;

  // Remove styling from last node with focus
  if (OAA_CI.last_node) {
    OAA_CI.last_node.style.outline = "";
  } // endif

  if (!cache_item) return;

  // Test to see if the cache item has a dom_element property
  if (cache_item.dom_element) {
    if (cache_item.dom_element.image_only) {
      node = cache_item.dom_element.node.getElementsByTagName("img")[0];
      pos_top  = Math.round(cache_item.dom_element.computed_style.top) + "px";
      pos_left = Math.round(cache_item.dom_element.computed_style.left) + "px";
    }
    else {
      node = cache_item.dom_element.node;
      pos_top  = Math.round(cache_item.dom_element.computed_style.top) + "px";
      pos_left = Math.round(cache_item.dom_element.computed_style.left) + "px";
    }
  }
  else {
    node = cache_item.node;
    pos_top  = Math.round(cache_item.computed_style.top) + "px";
    pos_left = Math.round(cache_item.computed_style.left) + "px";
  }

  if (node) {
    node.style.outline = "medium solid red";
//    OpenAjax.a11y.console("x="+ pos_top + " y=" + pos_top );
    window.scrollTo(pos_left, pos_top);
    OAA_CI.last_node = node;
  }

}

/** ================================================================
*
* showCacheItemProperties
*
* @desc cache_item Object OAA Cache item
*
* @return nothing
*
* =============================================================== */

OAA_CI.showCacheItemProperties = function (cache_item) {

  function addRow (object, property_name ) {
    if ( typeof object[property_name] == 'function') return;
    this_object.addTreeItemPropertyNameAndValue(advanced_treechildren, property_name, object[property_name]);
  }

  function showStyleProperties(object ) {
    for (var property_name in object ) {
      if( typeof object[property_name] != 'function') {
        this_object.addTreeItemPropertyNameAndValue(style_treechildren, property_name, object[property_name]);
      }
    }  // end loop
  }

  function showEventInformation(object ) {
    for (var property_name in object ) {
      if( typeof object[property_name] != 'function') {
        this_object.addTreeItemPropertyNameAndValue(event_treechildren, property_name, object[property_name]);
      }
    }  // end loop
  } // end function

  function showRuleResult( property, result, rule_result_objects ) {

    var length = rule_result_objects.length;

    for(var i=0; i < length; i++ ) {

      var treeitem = document.createElement('treeitem');
      var treerow  = document.createElement('treerow');

      var treecell = document.createElement('treecell');
      treecell.setAttribute('label', result);
      treecell.setAttribute('property', property);
      treerow.appendChild(treecell);

      var treecell = document.createElement('treecell');
      treecell.setAttribute('label', rule_result_objects[i].getResult(this_object.evaluation.ruleset_nls));
      treerow.appendChild(treecell);

      treeitem.appendChild(treerow);

      rule_treechildren.appendChild(treeitem);

    } // end loop

  }  // end function

  function showDOMElementProperties (object ) {

    for (var property_name in object ) {

      switch (property_name) {

      case "computed_style":
        showStyleProperties( object["computed_style"]);
        break;

      case "events":
        showEventInformation( object["events"]);
        break;

      case "rules_violation":
        showRuleResult( "v", "V", object["rules_violation"]);
        break;

      case "rules_potential_violation":
        showRuleResult( "pv", "PV",    object["rules_potential_violation"]);
        break;

      case "rules_recommendation":
        showRuleResult( "r", "R", object["rules_recommendation"]);
        break;

      case "rules_potential_recommendation":
        showRuleResult( "pr", "PR", object["rules_potential_recommendation"]);
        break;

      case "rules_passed":
        showRuleResult( "passed", "Passed", object["rules_passed"]);
        break;

      case "rules_na":
        showRuleResult( "na", "N/A", object["rules_na"]);
        break;

      default:
        if( typeof object[property_name] != 'function') {
          this_object.addTreeItemPropertyNameAndValue(common_treechildren, property_name, object[property_name]);
        }
        break;
      } // end switch
    } // end loop
  } // end function


  function showObjectProperties (object ) {

    if ( object['dom_element'] || object['dom_elements']) {
      for (var property_name in object ) {
        if (property_name == "dom_element") {
          showDOMElementProperties( object["dom_element"]);
        }
        else {
          addRow(object, property_name);
        }
      }  // end loop
    }
    else {
      showDOMElementProperties(object);
    }
  } // end function

  // For use in the enclosed functions
  var this_object = this;

  // get reference to the tree column widget
  var rule_treechildren     = document.getElementById('ID_RULE_TREECHILDREN');
  var advanced_treechildren = document.getElementById('ID_ADVANCED_TREECHILDREN');
  var common_treechildren   = document.getElementById('ID_COMMON_TREECHILDREN');
  var style_treechildren    = document.getElementById('ID_STYLE_TREECHILDREN');
  var event_treechildren    = document.getElementById('ID_EVENT_TREECHILDREN');

  //  OpenAjax.a11y.console(" Found: " + treechildren);

  // Remove current content from tree
  OAA_CI.removeChildNodes(rule_treechildren);
  OAA_CI.removeChildNodes(advanced_treechildren);
  OAA_CI.removeChildNodes(common_treechildren);
  OAA_CI.removeChildNodes(style_treechildren);
  OAA_CI.removeChildNodes(event_treechildren);

  if (cache_item) {
    showObjectProperties(cache_item);
    OAA_CI.highlightCacheItem(cache_item);
  }

}

/** ================================================================
*
* evaluateDocument
*
* @desc opens the log information window
*
* @param window Object window object of document to be analyzed
*
* @return nothing
*
* =============================================================== */

OAA_CI.evaluateDocument = function () {

  var doc;
  var title;
  var url;
  // Get reference to the rendered document (Firefox)
  try {
      doc = window.content.document;
      title = doc.title;
      url = window.content.location.href;
  } catch(e) {
      doc  = window.opener.parent.content.document;
      title = doc.title;
      url = window.opener.parent.location.href;
  } // end try

  OAA_CI.updateProgress("", 0);

  OpenAjax.a11y.CONSOLE_MESSAGES = true;
  OpenAjax.a11y.SUPPORTS_EVENT_ANALYSIS = true;  // enable collecting information about events

  OAA_CI.evaluation = new OpenAjax.a11y.RulesetEvaluation('WCAG_2_0', 'en-us', url, title, doc, OAA_CI.updateProgress);
  OAA_CI.evaluation.evaluate(true);

  if (OAA_CI_UTILS) {
    OAA_CI_UTILS.result  = OAA_CI.evaluation.ruleset_result;
    OAA_CI_UTILS.log     = OAA_CI.evaluation.log;
    OpenAjax.a11y.console("Updated common variables");
  }
  else {
    OpenAjax.a11y.console("UNABLE to update common variables");
  }

}

/** ================================================================
*
* createXULElement
*
* @desc creates a XUL element with the specified attributes
*
* @param element    String name of XUL element to create
* @param attributes String Array of strings with the format name=value
*
* @return XUL element object
*
* =============================================================== */

OAA_CI.createXULElement = function (element, attributes) {

  var xul_element = document.createElement(element);

  var attributes_length = attributes.length;

  for (var i=0; i < attributes_length; i++ ) {

     var attribute_value = attributes[i].split('=');

     if ( attribute_value.length == 2) {
       xul_element.setAttribute(attribute_value[0],attribute_value[1]);
     }
     else {
       if ( attribute_value.length == 1) {
         xul_element.setAttribute(attribute_value[0],"");
       }
     }

  } // end loop

  return xul_element;

}

/** ================================================================
*
* removeChildNodes
*
* @desc removes the child nodes of a DOM object
*
* @param node     Object DOM node object
*
* @return nothing
*
* =============================================================== */

OAA_CI.removeChildNodes = function (node) {

  if (node && node.hasChildNodes()) {
        while (node.firstChild) {
          node.removeChild(node.firstChild );
        }
  }
}

/** ================================================================
*
* setTreeColumnLabels
*
* @desc creates a XUL element with the specified attributes
*
* @param xul_tree      Object XUL tree object to update column labels
* @param column_labels Array  array of strings for the column label text
* @param flex_values   Array  array of Numbers used as the flex value for each column
*
* @return Object of XUL tree
*
* =============================================================== */

OAA_CI.setTreeColumnLabels = function(xul_tree, column_labels, flex_values) {

    OAA_CI.removeChildNodes(xul_tree);

    var xul_treecols = OAA_CI.createXULElement('treecols',[]);

    var column_length = column_labels.length;

    for (var i=0; i < column_length; i++ ) {

      var xul_treecol = OAA_CI.createXULElement('treecol',['flex='+flex_values[i]]);
      xul_treecol.setAttribute('label', column_labels[i] );
      xul_treecols.appendChild(xul_treecol);

      var xul_splitter = OAA_CI.createXULElement('splitter',['class=tree-splitter']);
      xul_treecols.appendChild(xul_splitter);

    } // end loop

    xul_tree.appendChild(xul_treecols);

    var xul_treechildren = OAA_CI.createXULElement('treechildren',[]);
    xul_treechildren.id = 'ID_CACHE_ITEMS_CHILDREN';
    xul_tree.appendChild(xul_treechildren);

    return xul_treechildren;

}

/** ================================================================
*
* addTreeRow
*
* @desc creates a XUL element with the specified attributes
*
* @param xul_treeitem   Object   XUL treeitem object to update column labels
* @param items          Array    array of items for the row
* @param value          String   if defined sets the value property of the treecell with string
*
* @return
*
* =============================================================== */

OAA_CI.addTreeRow = function (xul_treeitem, items, value) {

  var xul_treerow = document.createElement('treerow');

  if (value) xul_treerow.setAttribute('value', value);

  var items_length = items.length;

  for (var i=0; i < items_length; i++ ) {

    var xul_treecell = document.createElement('treecell');

    if (i==0 && value && value.length) {
       xul_treecell.setAttribute("value", value);
    }

    xul_treecell.setAttribute('label', items[i]);

    xul_treecell.setAttribute('crop', 'end' );

    xul_treerow.appendChild(xul_treecell);

  } // end loop

  xul_treeitem.appendChild(xul_treerow);

}

/** ================================================================
*
* addTreeItem
*
* @desc
*
* @param xul_treechidren  Object   DOM node whos childres contain XUL treeitems
* @param cache_item       Object   object in a list of cache objects
* @param properties       Array    array of property names to display in the row
* @param value            String   if defined sets the value property of the treecell with string
*
* @return
*
* =============================================================== */

OAA_CI.addTreeItem = function (xul_treechildren, cache_item, properties, value) {

  var xul_treeitem = document.createElement('treeitem');

  OAA_CI.addTreeRow(xul_treeitem, cache_item, properties, value);

  xul_treechildren.appendChild(xul_treeitem);

}

/** ================================================================
*
* addTreeChildrenPropertyValueItem
*
* @desc
*
* @param xul_treechildren  Object   DOM node of a XUL treechildren element
* @param property          String   property name
* @param value             String   array of property names to display in the row
*
* @return
*
* =============================================================== */

OAA_CI.addTreeItemPropertyNameAndValue = function (xul_treechildren, property, value) {

  var xul_treeitem = document.createElement('treeitem');
  var xul_treerow  = document.createElement('treerow');

  var xul_treecell = document.createElement('treecell');
  xul_treecell.setAttribute('label', property);
  xul_treerow.appendChild(xul_treecell);

  var xul_treecell = document.createElement('treecell');
  xul_treecell.setAttribute('label', value);
  xul_treerow.appendChild(xul_treecell);

  xul_treeitem.appendChild(xul_treerow);

  xul_treechildren.appendChild(xul_treeitem);

}

/** ================================================================
*
* onPropertyElementItemsSelectChanged
*
* @desc
*
* @param event Object Event object
*
* @return
*
* =============================================================== */

OAA_CI.onPropertyElementItemsSelectChanged = function(event) {

  var xul_tree = event.target;
  var index = event.target.currentIndex;

  var col1_id   = xul_tree.columns.getColumnAt(0);
  var col1_text = xul_tree.view.getCellText(index, col1_id);

  var col2_id   = xul_tree.columns.getColumnAt(1);
  var col2_text = xul_tree.view.getCellText(index, col2_id);



  var xul_label = document.getElementById('ID_PROPERTY_LABEL');
  xul_label.value = col1_text;

  var xul_textbox = document.getElementById('ID_PROPERTY_TEXTBOX');
  if (col2_text) {
    xul_textbox.value = col2_text;
  }
  else {
    xul_textbox.value = "";
  }


}



window.addEventListener("load", function () { OAA_CI.onLoad(); }, false);

